/**
 * 请求封装
 * 处理请求拦截、响应拦截和错误处理
 */

// 服务器地址
const BASE_URL = 'http://192.168.0.10:8080/api'; // 替换为实际的API地址
const BASE_URL_V1 = 'http://192.168.0.10/api/v1'; // 替换为实际的API地址


// 请求超时时间
const TIMEOUT = 15000;

// 请求拦截器
const requestInterceptor = (config) => {
	// 获取token
	const token = uni.getStorageSync('token');

	// 如果有token，添加到header
	if (token) {
		config.header = {
			...config.header,
			'Authorization-ads': `Bearer ${token}`
		};
	}

	return config;
};

// 响应拦截器
const responseInterceptor = (response) => {
	if (response.statusCode === 200) {
		// 服务器正常响应
		const {
			code,
			msg,
			data
		} = response.data;
		console.log(data);

		// 判断业务状态码
		if (code === 200 || code === 0) {
			// 业务成功
			return data;
		} else {
			// 业务失败
			const error = new Error(msg || '服务器返回错误');
			error.code = code;
			throw error;
		}
	} else {
		// HTTP错误
		const error = new Error(`HTTP错误: ${response.statusCode}`);
		error.statusCode = response.statusCode;
		throw error;
	}
};

// 统一错误处理
const handleError = (error) => {
	// 根据错误类型显示不同提示
	let message = error.message || '请求失败';

	// 处理超时错误
	if (error.message && error.message.includes('timeout')) {
		message = '请求超时，请检查网络';
	}

	// 处理网络错误
	if (error.errMsg && error.errMsg.includes('fail')) {
		message = '网络连接失败，请检查网络';
	}

	// 处理特定业务错误码
	if (error.code) {
		switch (error.code) {
			case 401:
				message = '未授权，请重新登录';
				// 清除登录状态，跳转到登录页
				uni.removeStorageSync('token');
				uni.removeStorageSync('userInfo');
				// 延迟跳转，给用户看到提示
				setTimeout(() => {
					uni.reLaunch({
						url: '/pages/login/index'
					});
				}, 1500);
				break;
			case 403:
				message = '拒绝访问，权限不足';
				break;
			case 404:
				message = '请求的资源不存在';
				break;
			case 500:
				message = '服务器错误';
				break;
			default:
				// 使用服务器返回的错误消息
				break;
		}
	}

	// 显示错误提示
	uni.showToast({
		title: message,
		icon: 'none',
		duration: 2000
	});

	// 返回错误对象，便于上层处理
	return Promise.reject(error);
};

/**
 * 发送请求的核心函数
 * @param {Object} options - 请求配置
 * @returns {Promise} - 返回Promise对象
 */
const request = (options = {}) => {
	// 合并请求配置
	const config = {
		url: options.url || '',
		method: options.method || 'GET',
		data: options.data || {},
		header: options.header || {
			'Content-Type': 'application/json',
			'Authorization': `Bearer ${uni.getStorageSync('apiKey')}`,
			'Authorization-ads': `Bearer ${uni.getStorageSync('token')}`

		},
		timeout: options.timeout || TIMEOUT,
		dataType: options.dataType || 'json',
	};

	// 判断 url 是否包含 http，如果不包含则添加 BASE_URL
	if (!config.url.startsWith('http')) {
		if (options.v1) {
			config.url = BASE_URL_V1 + config.url;
		} else {
			config.url = BASE_URL + config.url;
		}
	}

	// 应用请求拦截器
	const finalConfig = requestInterceptor(config);

	// 返回 Promise
	return new Promise((resolve, reject) => {
		uni.request({
			...finalConfig,
			success: (res) => {
				try {
					const data = responseInterceptor(res);
					resolve(data);
				} catch (error) {
					handleError(error).catch(reject);
				}
			},
			fail: (err) => {
				handleError(err).catch(reject);
			}
		});
	});
};

/**
 * GET请求
 * @param {string} url - 请求地址
 * @param {Object} data - 请求参数
 * @param {Object} options - 其他配置项
 * @returns {Promise} - 返回Promise对象
 */
const get = (url, data = {}, options = {}) => {
	return request({
		...options,
		url,
		data,
		method: 'GET'
	});
};

/**
 * GET请求
 * @param {string} url - 请求地址
 * @param {Object} data - 请求参数
 * @param {Object} options - 其他配置项
 * @returns {Promise} - 返回Promise对象
 */
const download = (datasetId, fileId) => {
	return new Promise((resolve, reject) => {
		return uni.downloadFile({
			url: BASE_URL_V1 + '/datasets/' + datasetId + '/documents/' + fileId,
			header: {
				'Authorization': `Bearer ${uni.getStorageSync('apiKey')}`
			},
			success: (res) => {
				resolve(res);
			},
			fail: (err) => {
				reject(err);
			}
		});
	})

};

/**
 * POST请求
 * @param {string} url - 请求地址
 * @param {Object} data - 请求参数
 * @param {Object} options - 其他配置项
 * @returns {Promise} - 返回Promise对象
 */
const post = (url, data = {}, options = {}) => {
	return request({
		...options,
		url,
		data,
		method: 'POST'
	});
};

/**
 * PUT请求
 * @param {string} url - 请求地址
 * @param {Object} data - 请求参数
 * @param {Object} options - 其他配置项
 * @returns {Promise} - 返回Promise对象
 */
const put = (url, data = {}, options = {}) => {
	return request({
		...options,
		url,
		data,
		method: 'PUT'
	});
};

/**
 * DELETE请求
 * @param {string} url - 请求地址
 * @param {Object} data - 请求参数
 * @param {Object} options - 其他配置项
 * @returns {Promise} - 返回Promise对象
 */
const del = (url, data = {}, options = {}) => {
	return request({
		...options,
		url,
		data,
		method: 'DELETE'
	});
};

/**
 * 上传文件
 * @param {string} url - 上传地址
 * @param {string} filePath - 文件路径
 * @param {string} name - 文件对应的 key
 * @param {Object} formData - 附加的表单数据
 * @param {Object} options - 其他配置项
 * @returns {Promise} - 返回Promise对象
 */
const upload = (options = {}) => {
	// 获取token
	const token = uni.getStorageSync('token');
	const header = options.header || {};

	if (token) {
		header.Authorization = 'Bearer ragflow-IyNmI3NjZjMDNiZTExZjA5YjQ5MDI0Mm'
		header['Authorization-ads'] = `Bearer ${token}`
	}

	// 返回 Promise
	return new Promise((resolve, reject) => {
		uni.uploadFile({
			url: options.url.startsWith('http') ? options.url : options.v1 ? BASE_URL_V1 + options
				.url : BASE_URL + options.url,
			filePath: options.filePath,
			name: options.name,
			formData: options.formData,
			header,
			success: (res) => {
				try {
					if (res.statusCode === 200) {
						// 解析返回的数据
						const data = JSON.parse(res.data);
						if (data.code === 200 || data.code === 0) {
							resolve(data.data);
						} else {
							const error = new Error(data.msg || '上传失败');
							error.code = data.code;
							throw error;
						}
					} else {
						throw new Error(`HTTP错误: ${res.statusCode}`);
					}
				} catch (error) {
					handleError(error).catch(reject);
				}
			},
			fail: (err) => {
				handleError(err).catch(reject);
			}
		});
	});
};

// 导出API函数
export default {
	request,
	get,
	post,
	put,
	delete: del, // delete是关键字，所以导出时用del重命名
	upload,
	download,
	BASE_URL,
	BASE_URL_V1
};